#!/usr/bin/env ppython

import bluetooth, socket
import ledcube, connection

class SocketServer:
	def __init__(self):
		if self.__class__ == SocketServer:
			raise Exception("Please use subclass!")
	
	def get_fd(self):
		return self.server.fileno()
	
	def accept(self):
		client, address = self.server.accept()
		print "Accepted connection from [%s]:%d" % address
		return client
	

class NetworkServer(SocketServer):
	def __init__(self):
		self.port = 54145
		
		self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		
		self.server.bind(("", self.port))
		self.server.listen(1)
		
		print "listening on [%s]:%d" % self.server.getsockname()
	

class BluetoothServer(SocketServer):
	def __init__(self):
		self.uuid = "00001101-0000-1000-8000-00805F9B34FB"
		self.sdpname = "LEDCube"
		self.port = 10
		
		self.server = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
		
		self.server.bind(("", self.port))
		self.server.listen(1)
		
		bluetooth.advertise_service(
			self.server,
			self.sdpname,
			self.uuid,
			service_classes=[bluetooth.SERIAL_PORT_CLASS],
			profiles=[bluetooth.SERIAL_PORT_PROFILE]
		)
		
		print "listening on [%s]:%d" % self.server.getsockname()
	
	def accept(self):
		socket = SocketServer.accept(self)
		return SocketWrapper(socket)

class SocketWrapper:
	def __init__(self, socket):
		self.__socket = socket
		
		def wrap(name):
			func = getattr(self.__socket, name)
			def anon(*args):
				try:
					return func(*args)
				except bluetooth.BluetoothError as e:
					raise EOFError(e)
			return anon
		
		for i in ("send", "recv"):
			setattr(self, i, wrap(i))
	

def start_server():
	server_nw = NetworkServer()
	server_bt = BluetoothServer()
	
	cube = ledcube.VirtualLEDCube(5, 5, 10, 0.1)
	
	cubeconnection = connection.CubeConnection(cube, (server_bt, server_nw))
	cube.run()

def usage():
		print "Available server types: %s" % ", ".join(known_servers.keys())
	

if __name__ == "__main__":
	import sys
	if len(sys.argv) != 1:
		print "Usage: %s" % sys.argv[0]
		sys.exit(1)
	
	start_server()
	

